--测试环境
--package.path = package.path..";?.lua"
--生产环境
package.path = "./plugin/CMIO08/utils.lua"..";..\\?.lua"
package.path = "./plugin/CMIO08/json.lua"..";..\\?.lua"


require ("utils")
require ("json")

rxBuf = {}
regAddr = 0x0000

function NewVariables()
    -- body
    local VariableMap = {
        Variable = {
        },
    }

    return VariableMap
end

function GetRealVariables(sAddr,step,variables)
    -- body
    local crc
    local requestADU = {}
    local requestADULen = 0
    local VariableMap = {
        Status = "0",
        Variable = {},
    }

    if(step == 0)
    then
        ---------------------------
        requestADU[1] = sAddr --通信地址
        requestADU[2] = 0x01  --功能码
        requestADU[3] = 0x00  --寄存器地址
        requestADU[4] = 0x00
        requestADU[5] = 0x00
        requestADU[6] = 0x08  --寄存器数量
        local VariableMapTemp = {
            Variable = requestADU
        }
        crc = GetCRCModbus(VariableMapTemp)
        requestADU[7] = math.modf(crc%256) --CRC校验
        requestADU[8] = math.modf(crc/256)

        requestADULen = 8

        VariableMap = {
            Status = "0",
            Variable = requestADU
        }
        regAddr = 0x0000
    end

    local tmp = ""
    for i=1,requestADULen,1 do
        tmp = tmp .. " " .. string.format("%02X",requestADU[i])
    end
    --print(tmp)

    return VariableMap
end

function SetRealVariables(sAddr,cmdName,cmdParam,step,variables)
    -- body
    local crc
    local requestADU = {}
    local requestADULen = 0
    local VariableMap = {
        Status = "0",
        Variable = {},
    }

    if(step == 0)
    then
        res = json.jsondecode(cmdParam)
        local IoOutName = { "IoOut1", "IoOut2", "IoOut3","IoOut4", "IoOut5", "IoOut6", "IoOut7", "IoOut8"}

        for pIndex = 1, #IoOutName, 1 do
            local name = IoOutName[pIndex]
            if(res[name] ~= nil) then--开关设定
                local IoOut1 = tonumber(res[name])
                requestADU[1] = sAddr
                requestADU[2] = 0x05
                requestADU[3] = 0x00
                requestADU[4] = pIndex-1
                if (IoOut1 == 0) then
                    requestADU[5] = 0x00
                    requestADU[6] = 0x00
                else
                    requestADU[5] = 0xFF
                    requestADU[6] = 0x00
                end
                local VariableMapTemp = {
                    Variable = requestADU
                }
                crc = GetCRCModbus(VariableMapTemp)
                requestADU[7] = math.modf(crc%256)
                requestADU[8] = math.modf(crc/256)

                VariableMap = {
                    Status = "0",
                    Variable = requestADU
                }
            end
        end
    end

    local tmp = ""
    for i=1,requestADULen,1 do
        tmp = tmp .. " " .. string.format("%02X",requestADU[i])
    end
    --print(tmp)

    return VariableMap
end

function GenerateGetRealVariables(sAddr,step,variables)

    return GetRealVariables(sAddr,step,variables)
end

function DeviceCustomCmd(sAddr,cmdName,cmdParam,step,variables)

    if(cmdName == "GetRealVariables")
    then
        VariableMap = GetRealVariables(sAddr,step,variables)
    elseif(cmdName == "SetVariables")
    then
        VariableMap = SetRealVariables(sAddr,cmdName,cmdParam,step,variables)
    end

    return VariableMap
end

function AnalysisRx(sAddr,rxBufCnt)

    --local index = 1
    local mAddr = 0
    local mFunCode = 0
    local mRegByte = 0
    local crc,crcTemp

    -- body
    local VariableMap = {
        Status = "1",
        Variable = {},
    }

    --modbus回应帧最短为5个字节 地址(1)+功能码(1)+数据域(>=1)+校验(2)
    if(rxBufCnt < 5)
    then
        rxBuf = {}
        VariableMap = {
            Status = "1",
            Variable = {},
        }
        return VariableMap
    end


    for index=1,rxBufCnt,1 do
        if((index+4) <= rxBufCnt)  --因为index是从1开始的，所以是+4
        then
            mAddr     = rxBuf[index]
            if(mAddr == tonumber(sAddr))  --判断通信地址
            then
                mFunCode  = rxBuf[index+1]
                if((mFunCode==0x81) or   --故障码
                        (mFunCode==0x82) or
                        (mFunCode==0x83) or
                        (mFunCode==0x84))
                then
                    VariableMap = {
                        Status = "1",
                        Variable = {},
                    }
                    rxBuf = {}
                    return VariableMap
                end
                if(mFunCode == 0x01)
                then
                    mRegByte = rxBuf[index+2]
                    if(mRegByte+5 > rxBufCnt)
                    then
                        rxBuf = {}
                        return VariableMap
                    end
                    --取出数据域数据
                    local pdu = {}
                    for i=index,index+2+mRegByte,1 do
                        if rxBuf[i] ~= nil then
                            table.insert(pdu, rxBuf[i])
                        end
                    end
                    local VariableMapCRC = {
                        Variable = pdu
                    }
                    crc = GetCRCModbus(VariableMapCRC)
                    crcTemp = rxBuf[index+3+mRegByte+1]*256+rxBuf[index+3+mRegByte]
                    if(crc == crcTemp)
                    then
                        local Variable = {}
                        local varIndex = 3
                        local VariableIndex = 1
                        if(regAddr == 0x0000)
                        then
                            -------------------------------------------------------------
                            local IoOutStatus = rxBuf[index+varIndex]
                            varIndex = varIndex + 1
                            local params1 = { "IoOut1", "IoOut2", "IoOut3","IoOut4", "IoOut5", "IoOut6", "IoOut7", "IoOut8"}
                            local params2 = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}
                            for pIndex = 1, #params1, 1 do
                                local status = utils.And(IoOutStatus,params2[pIndex])
                                Variable[VariableIndex] = utils.AppendVariable(VariableIndex, params1[pIndex], status, status)
                                VariableIndex = VariableIndex + 1
                            end
                            -------------------------------------------------------------
                            VariableMap = {
                                Status = "0",
                                Variable = Variable
                            }
                        end
                        rxBuf = {}
                        return VariableMap
                    end
                elseif(mFunCode == 0x03)
                then
                    mRegByte = rxBuf[index+2]
                    if(mRegByte+5 > rxBufCnt)
                    then
                        rxBuf = {}
                        return VariableMap
                    end
                    --取出数据域数据
                    local pdu = {}
                    for i=index,index+2+mRegByte,1 do
                        if rxBuf[i] ~= nil then
                            table.insert(pdu, rxBuf[i])
                        end
                    end
                    local VariableMapCRC = {
                        Variable = pdu
                    }
                    crc = GetCRCModbus(VariableMapCRC)
                    crcTemp = rxBuf[index+3+mRegByte+1]*256+rxBuf[index+3+mRegByte]
                    if(crc == crcTemp)
                    then
                        local Variable = {}
                        local VariableIndex = 1
                        local DATAIndex = index+3
                        if(regAddr == 0x0000) then
                            ---------解析湿度数据并加入上报的map中----------------------
                            local humiValue = rxBuf[DATAIndex]*256+rxBuf[DATAIndex+1]
                            DATAIndex = DATAIndex + 2
                            Variable[VariableIndex]  = utils.AppendVariable(VariableIndex,"Humi",humiValue,string.format( "%2.1f",humiValue/10.0))
                            VariableIndex = VariableIndex + 1
                             ---------解析温度数据并加入上报的map中----------------------
                            local tempValue = rxBuf[DATAIndex]*256+rxBuf[DATAIndex+1]
                            DATAIndex = DATAIndex + 2
                            --tempValue = utils.Complement(tempValue)
                            Variable[VariableIndex]  = utils.AppendVariable(VariableIndex,"Temp",tempValue,string.format( "%2.1f",tempValue/10.0))
                            VariableIndex = VariableIndex + 1
                            --------------------------------------------------------
                            VariableMap = {
                                Status = "0",
                                Variable = Variable
                            }
                        end
                        rxBuf = {}
                        return VariableMap
                    end
                elseif(mFunCode == 0x05)
                then
                    mRegAddr = rxBuf[index+2]*256+rxBuf[index+3]
                    --取出数据域数据
                    local pdu = {}
                    for i=index,index+5,1 do
                        if rxBuf[i] ~= nil then
                            table.insert(pdu, rxBuf[i])
                        end
                    end
                    local VariableMapCRC = {
                        Variable = pdu
                    }
                    crc = GetCRCModbus(VariableMapCRC)
                    crcTemp = rxBuf[index+6+1]*256+rxBuf[index+6]
                    if(crc == crcTemp)
                    then
                        VariableMap = {
                            Status = "0",
                            Variable = {}
                        }
                        rxBuf = {}
                        print("crc ok")
                        return VariableMap
                    end
                    print("crc error")
                elseif(mFunCode == 0x06)
                then
                    mRegAddr = rxBuf[index+2]*256+rxBuf[index+3]
                    --取出数据域数据
                    local pdu = {}
                    for i=index,index+5,1 do
                        if rxBuf[i] ~= nil then
                            table.insert(pdu, rxBuf[i])
                        end
                    end
                    local VariableMapCRC = {
                        Variable = pdu
                    }
                    crc = GetCRCModbus(VariableMapCRC)
                    crcTemp = rxBuf[index+6+1]*256+rxBuf[index+6]
                    if(crc == crcTemp)
                    then
                        VariableMap = {
                            Status = "0",
                            Variable = {},
                        }
                        rxBuf = {}
                        return VariableMap
                    end       
                elseif(mFunCode == 0x10)
                then
                    VariableMap = {
                        Status = "0",
                        Variable = {},
                    }
                    rxBuf = {}
                    return VariableMap
                else
                    index = index + 1
                end 
            end
        end
    end

    rxBuf = {}
    return VariableMap
end
